package miniAES;

public class assembly {
    //S盒
    public static byte [] sBox=new byte[]{0xc,0x5,0x6,0xb,0x9,0x0,0xa,0xd,0x3,0xe,0xf,0x8,0x4,0x7,0x1,0x2};
    //S盒的逆
    public static byte [] inSbox=new byte[]{0x5,0xe,0xf,0x8,0xc,0x1,0x2,0xd,0xb,0x4,0x6,0x3,0x0,0x7,0x9,0xa};
    //列混淆[逆为本身]
    //private static byte [] mixConstant=new byte[]{0x3,0x2,0x2,0x3};
    private assembly (){}

    //S盒运算
    public static byte[] nibbleSub(byte inPut[]){
        for (int i = 0; i < 4; i++) {
            inPut[i]=sBox[inPut[i]];
        }
        return inPut;
    }
    //S盒逆运算
    public static byte[] nibbleInSub(byte inPut[]){
        for (int i = 0; i < 4; i++) {
            inPut[i]=inSbox[inPut[i]];
        }
        return inPut;
    }
    //行移位 逆为自身
    public  static byte[] shiftRow(byte input[]){
       byte temp=input[1];
       input[1]=input[3];
       input[3]=temp;

       return input;
    }
    //列混淆 逆位自身
    public static byte[] mixColumn(byte input[],byte output[]){
        output[0]=(byte) (gfMultiplication((byte) 3,input[0])^gfMultiplication((byte) 2,input[1]));
        output[2]=(byte) (gfMultiplication((byte) 3,input[2])^gfMultiplication((byte) 2,input[3]));
        output[1]=(byte) (gfMultiplication((byte) 2,input[0])^gfMultiplication((byte) 3,input[1]));
        output[3]=(byte) (gfMultiplication((byte) 2,input[2])^gfMultiplication((byte) 3,input[3]));
        return output;
    }
    //密钥加
    public static byte[] keyAddition(byte input[],byte subkey[]){
        for (int i = 0; i < 4; i++) {
            input[i]= (byte) (input[i]^subkey[i]);
        }
        return input;
    }
    //列计算
    public static byte gfMultiplication(byte factor,byte input){
        byte temp=input;
        temp<<=1;
        if (factor==2){
            if ((temp & 0x10)==0x10){
                return (byte) (temp&0xf^0x3);
            }
            else return temp;
        }
        else {
            if ((temp & 0x10)==0x10){
                return (byte) (temp&0xf^0x3^input);
            }
            else return (byte) (temp^input);
        }
    }
    //以半字节输出
    public static void printBin(byte[] c ,int num) {
        for (int i = 0; i < num; i++) {
            System.out.print("0b"+Integer.toBinaryString(c[i]));
            if (i!=3){
                System.out.print(",");
            }else {
                System.out.println();
            }
        }
    }
}
